home *** CD-ROM | disk | FTP | other *** search
/ CDUTIL 13 / CDUTIL #13 Julio 1995.iso / windows / acadcom / ads / sample / calexpr.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-02-08  |  24.1 KB  |  958 lines

  1. /* Next available MSG number is   3 */
  2.  
  3. /*****************************************************************************
  4.       CALEXPR.C
  5.       (C) Copyright 1988-1994 by Autodesk, Inc.
  6.  
  7.       This program is copyrighted by Autodesk, Inc. and is  licensed
  8.       to you under the following conditions.  You may not distribute
  9.       or  publish the source code of this program in any form.   You
  10.       may  incorporate this code in object form in derivative  works
  11.       provided  such  derivative  works  are  (i.) are  designed and 
  12.       intended  to  work  solely  with  Autodesk, Inc. products, and 
  13.       (ii.)  contain  Autodesk's  copyright  notice  "(C)  Copyright  
  14.       1988-1993 by Autodesk, Inc."
  15.  
  16.       AUTODESK  PROVIDES THIS PROGRAM "AS IS" AND WITH  ALL  FAULTS.
  17.       AUTODESK  SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTY OF  MER-
  18.       CHANTABILITY OR FITNESS FOR A PARTICULAR USE.  AUTODESK,  INC.
  19.       DOES  NOT  WARRANT THAT THE OPERATION OF THE PROGRAM  WILL  BE
  20.       UNINTERRUPTED OR ERROR FREE.
  21.  
  22.   Description: The syntactic analysis of the expression based on
  23.                the context-free LL(1) grammar.
  24.  
  25.   Notes:
  26.  
  27.   The syntax of the expression:
  28.  
  29.   EXPR   = TERM   + TERM    ...
  30.   TERM   = POWER  * POWER  *...
  31.   POWER  = FACTOR ^ FACTOR ^...
  32.   FACTOR = +- NUMBER
  33.               VECTOR
  34.               (EXPR)
  35.               FUNC(EXPR,EXPR,...)
  36.               ......
  37.  
  38.   VECTOR = [EXPR,EXPR,EXPR]                                 
  39.  
  40. *****************************************************************************/
  41.  
  42.  
  43. /****************************************************************************/
  44. /*  INCLUDES                                                                */
  45. /****************************************************************************/
  46.  
  47. #define R12_EXTLISPADS 1              /* Enable extended AutoLISP/ADS funcs */
  48.  
  49. #include "cal.h"
  50.  
  51.  
  52. /****************************************************************************/
  53. /*  STATIC FUNCTIONS                                                        */
  54. /****************************************************************************/
  55.  
  56. static int  check_overflow    _((vector_real_int *value, int n));
  57. static void vector            _((vector_real_int *value));
  58. static void AutoLISP_variable _((vector_real_int *value));
  59. static void factor            _((vector_real_int *value));
  60. static void power             _((vector_real_int *value));
  61. static void term              _((vector_real_int *value));
  62. static void expr              _((vector_real_int *value));
  63.  
  64.  
  65. /****************************************************************************/
  66. /*.doc check_overflow(internal)*/
  67. /*+
  68.   Check whether overflow occured.
  69. -*/
  70. /****************************************************************************/
  71.  
  72.  
  73. static int
  74. /*FCN*/check_overflow(value, n)
  75.  
  76.   vector_real_int *value;             /* The value to check           */
  77.   int             n;                  /* Error to display if overflow */
  78.                                       /* 0=Default error message      */
  79. {
  80.     if (cal_err)
  81.         return(FALSE);
  82.  
  83.     if (n == 0) {
  84.         n = 23;                       /* Default error message */
  85.     }
  86.  
  87.     if ((errno == EDOM) || (errno == ERANGE)) {
  88.         error(n, NULL);
  89.         return(FALSE);
  90.     }
  91.     if (value->type == vector_type) {
  92.         if ((value->v[X] == HUGE_VAL) ||
  93.             (value->v[Y] == HUGE_VAL) ||
  94.             (value->v[Z] == HUGE_VAL))   {
  95.             error(n, NULL);
  96.             return(FALSE);
  97.         } else {
  98.             return(TRUE);
  99.         }
  100.     } else if (value->r == HUGE_VAL) {
  101.         error(n, NULL);
  102.         return(FALSE);
  103.     } else {
  104.         return(TRUE);
  105.     }
  106. } /*check_overflow*/
  107.  
  108.  
  109. /****************************************************************************/
  110. /*.doc vector(internal)*/
  111. /*+
  112.   Parsing the nonterminal symbol VECTOR=[EXPR,EXPR,EXPR].
  113. -*/
  114. /****************************************************************************/
  115.  
  116.  
  117. static void
  118. /*FCN*/vector(value)
  119.  
  120.   vector_real_int *value;
  121. {
  122.     ads_point       v, c;
  123.     double          r, fi, theta;
  124.     vector_real_int sub_expr;
  125.     int             cylindrical_cs, spherical_cs, relative_cs, world_cs;
  126.     struct resbuf   buff;
  127.  
  128.     if (cal_err)
  129.         return;
  130.  
  131.     cylindrical_cs = spherical_cs = relative_cs = world_cs = FALSE;
  132.     v[X] = v[Y] = v[Z] = 0.0;
  133.  
  134.     cal_next_symbol();
  135.  
  136.     if (cal_lex.sym == at_sym) {
  137.         relative_cs = TRUE;
  138.         cal_next_symbol();
  139.     }
  140.  
  141.     if (cal_lex.sym == asterisk_sym) {
  142.         world_cs = TRUE;
  143.         cal_next_symbol();
  144.     }
  145.  
  146.     if ((cal_lex.sym != comma_sym)    &&
  147.         (cal_lex.sym != lessthan_sym) &&
  148.         (cal_lex.sym != rbracket_sym)) {
  149.  
  150.         expr(&sub_expr);
  151.         if (cal_err)
  152.             return;
  153.  
  154.         if ((sub_expr.type != real_type) &&
  155.             (sub_expr.type != int_type)) {
  156.             error(6, NULL);
  157.             return;
  158.         }
  159.         v[X] = sub_expr.r;
  160.     }
  161.  
  162.     if ((cal_lex.sym == comma_sym) || (cal_lex.sym == lessthan_sym)) {
  163.         cylindrical_cs = (cal_lex.sym == lessthan_sym);
  164.         cal_next_symbol();
  165.  
  166.     } else if (cal_lex.sym == rbracket_sym) {
  167.         goto Vector_completed;
  168.     } else {
  169.         error(7, NULL);
  170.         return;
  171.     }
  172.  
  173.     if ((cal_lex.sym != comma_sym)    &&
  174.         (cal_lex.sym != lessthan_sym) &&
  175.         (cal_lex.sym != rbracket_sym)) {
  176.  
  177.         expr(&sub_expr);
  178.         if (cal_err)
  179.             return;
  180.  
  181.         if ((sub_expr.type != real_type) &&
  182.             (sub_expr.type != int_type)) {
  183.             error(6, NULL);
  184.             return;
  185.         }
  186.         v[Y] = sub_expr.r;
  187.     }
  188.  
  189.     if ((cal_lex.sym == comma_sym) || (cal_lex.sym == lessthan_sym)) {
  190.  
  191.         spherical_cs = (cal_lex.sym == lessthan_sym);
  192.         cal_next_symbol();
  193.  
  194.     } else if (cal_lex.sym == rbracket_sym) {
  195.         goto Vector_completed;
  196.     } else {
  197.         error(7, NULL);
  198.         return;
  199.     }
  200.  
  201.     if (cal_lex.sym != rbracket_sym) {
  202.  
  203.         expr(&sub_expr);
  204.  
  205.         if (cal_err)
  206.             return;
  207.  
  208.         if ((sub_expr.type != real_type) &&
  209.             (sub_expr.type != int_type)) {
  210.             error(6, NULL);
  211.             return;
  212.         }
  213.         v[Z] = sub_expr.r;
  214.     }
  215.  
  216. Vector_completed:
  217.  
  218.     if (cal_lex.sym == rbracket_sym) {
  219.         cal_next_symbol();
  220.     } else  {
  221.         error(8, NULL);
  222.         return;
  223.     }
  224.  
  225.     value->type = vector_type;
  226.  
  227.     if (relative_cs) {
  228.         ads_getvar(/*MSG0*/"LASTPOINT", &buff);
  229.  
  230.         if (world_cs) {
  231.             sa_u2w(buff.resval.rpoint, c);
  232.         } else {
  233.             CPY_PNT(c, buff.resval.rpoint);
  234.         }
  235.     } else {
  236.         c[X] = c[Y] = c[Z] = 0.0;;
  237.     }
  238.  
  239.     if (!cylindrical_cs && !spherical_cs) {
  240.         ADD_PNT(v, c, v);
  241.  
  242.     } else if (cylindrical_cs && !spherical_cs) {
  243.         r  = v[X];
  244.         fi = v[Y] * DEGRAD;
  245.  
  246.         v[X] = c[X] + r * cos(fi);
  247.         v[Y] = c[Y] + r * sin(fi);
  248.         v[Z] = c[Z] + v[Z];
  249.  
  250.     } else if (cylindrical_cs && spherical_cs) {
  251.         r     = v[X];
  252.         fi    = v[Y] * DEGRAD;
  253.         theta = v[Z] * DEGRAD;
  254.  
  255.         v[X] = c[X] + r * cos(fi) * cos(theta);
  256.         v[Y] = c[Y] + r * sin(fi) * cos(theta);
  257.         v[Z] = c[Z] + r * sin(theta);
  258.     } else {
  259.         error(35, NULL);
  260.         return;
  261.     }
  262.  
  263.     if (world_cs) {
  264.         sa_w2u(v, v);
  265.     }
  266.  
  267.     CPY_PNT(value->v, v);
  268.     check_overflow(value, 0);
  269.  
  270. } /*vector*/
  271.  
  272.  
  273. /****************************************************************************/
  274. /*.doc AutoLISP_variable(internal)*/
  275. /*+
  276.   Get value of AutoLISP variable.
  277. -*/
  278. /****************************************************************************/
  279.  
  280.  
  281. static void
  282. /*FCN*/AutoLISP_variable(value)
  283.  
  284.   vector_real_int *value;
  285. {
  286.     struct resbuf *rb = NULL;
  287.     int           success;
  288.     
  289.     if (cal_err)
  290.         return;
  291.  
  292.     success = ads_getsym(cal_lex.id, &rb);
  293.     
  294.     if ((success != RTNORM) || (rb == NULL)) {
  295.         error(45, cal_lex.id);
  296.         return;
  297.     }
  298.     
  299.     /* Check the resbuf type */
  300.     
  301.     switch (rb->restype) {
  302.  
  303.     case RTSHORT:
  304.         value->type = int_type;
  305.         value->r    = (double)rb->resval.rint;
  306.         break;
  307.     case RTREAL:
  308.         value->type = real_type;
  309.         value->r    = rb->resval.rreal;
  310.         break;
  311.     case RTPOINT:
  312.     case RT3DPOINT:
  313.         value->type = vector_type;
  314.         CPY_PNT(value->v, rb->resval.rpoint);
  315.         break;
  316.     default:
  317.         error(43, cal_lex.id);
  318.         return;
  319.     } /*switch*/
  320.  
  321.     ads_relrb(rb);
  322.     cal_next_symbol();
  323.  
  324. } /*AutoLISP_variable*/
  325.  
  326.  
  327. /****************************************************************************/
  328. /*.doc factor(internal)*/
  329. /*+
  330.   Parsing the nonterminal symbol FACTOR = NUMBER | FUNC() | VARIABLE |...
  331. -*/
  332. /****************************************************************************/
  333.  
  334.  
  335. static void
  336. /*FCN*/factor(value)
  337.  
  338.   vector_real_int *value;
  339. {
  340.     vector_real_int f;
  341.     int             success;
  342.     int             is_minus;
  343.  
  344.     if (cal_err)
  345.         return;
  346.  
  347.     /* Check the leading unary plus or minus */
  348.  
  349.     if (cal_lex.sym == minus_sym) {
  350.         is_minus = TRUE;
  351.         cal_next_symbol();
  352.     } else if (cal_lex.sym == plus_sym) {
  353.         is_minus = FALSE;
  354.         cal_next_symbol();
  355.     } else {
  356.         is_minus = FALSE;
  357.     }
  358.  
  359.     if (cal_lex.sym == ident_sym) {
  360.         AutoLISP_variable(&f);
  361.  
  362.     } else if (cal_lex.sym == func_sym) {
  363.  
  364.         vector_real_int par[MAX_FUNC_PARAM];
  365.         int             nop;
  366.         void            (*func_ptr)();
  367.         char            func_name[MAX_SYMBOL_LENGTH+1];
  368.         int             i;
  369.  
  370.         func_ptr = cal_lex.func_ptr;
  371.         strcpy(func_name, cal_lex.id);
  372.         nop = 0;
  373.         cal_next_symbol();
  374.  
  375.         if (cal_lex.sym == lparent_sym) {
  376.             cal_next_symbol();
  377.  
  378.             while (!cal_err                     &&
  379.                    (cal_lex.sym != rparent_sym) &&
  380.                    (nop < MAX_FUNC_PARAM)) {
  381.  
  382.                 expr(&par[nop++]);
  383.  
  384.                 if (cal_lex.sym == comma_sym) {
  385.                     cal_next_symbol();
  386.                 } else if (cal_lex.sym != rparent_sym) {
  387.                     error(49, func_name);
  388.                     return;
  389.                 }
  390.             } /*while*/
  391.  
  392.             if (cal_lex.sym != rparent_sym) {
  393.                 error(50, func_name);
  394.                 return;
  395.             } else {
  396.                 cal_next_symbol();
  397.             }
  398.         } /*if*/
  399.  
  400.         if (cal_err)
  401.             return;
  402.  
  403.         /* Pass the actual function arguments */
  404.  
  405.         no_of_params = nop;
  406.         for (i = 0; i < nop; i++) {
  407.             params[i] = par[i];
  408.         }
  409.  
  410.         /* Call the function */
  411.  
  412.         (*func_ptr)();
  413.         if (cal_err)
  414.             return;
  415.  
  416.         f = result;
  417.  
  418.     } else if (cal_lex.sym == real_sym) {
  419.         f.type = real_type;
  420.         f.r    = cal_lex.real_num;
  421.         cal_next_symbol();
  422.  
  423.     } else if (cal_lex.sym == int_sym) {
  424.         f.type = int_type;
  425.         f.r    = cal_lex.real_num;
  426.         cal_next_symbol();
  427.  
  428.     } else if (cal_lex.sym == pi_sym) {
  429.         f.type = real_type;
  430.         f.r    = PI;
  431.         cal_next_symbol();
  432.  
  433.     } else if (cal_lex.sym == getvar_sym) {
  434.         struct resbuf buff;
  435.         
  436.         cal_next_symbol();
  437.         if (cal_lex.sym != lparent_sym) {
  438.             error(26, /*MSG1*/"GETVAR(AutoCAD_system_variable)");
  439.             return;
  440.         }
  441.         
  442.         cal_next_symbol();
  443.         if (cal_lex.sym != ident_sym) {
  444.             error(26, /*MSG2*/"GETVAR(AutoCAD_system_variable)");
  445.             return;
  446.         }
  447.         success = ads_getvar(cal_lex.id, &buff);
  448.         if (success != RTNORM) {
  449.             error(32, cal_lex.id);
  450.             return;
  451.         }
  452.  
  453.         switch (buff.restype) {
  454.  
  455.         case RTPOINT:
  456.         case RT3DPOINT:
  457.             f.type = vector_type;
  458.             CPY_PNT(f.v, buff.resval.rpoint);
  459.             break;
  460.         case RTREAL:
  461.         case RTANG:
  462.         case RTORINT:
  463.             f.type = real_type;
  464.             f.r    = buff.resval.rreal;
  465.             break;
  466.         case RTSHORT:
  467.             f.type = int_type;
  468.             f.r    = buff.resval.rint;
  469.             break;
  470.         case RTLONG:
  471.             f.type = int_type;
  472.             f.r    = buff.resval.rlong;
  473.             break;
  474.         default:
  475.             if (buff.restype == RTSTR)
  476.                 free(buff.resval.rstring);
  477.             error(33, NULL);
  478.             return;
  479.         } /*switch*/
  480.  
  481.         cal_next_symbol();
  482.         if (cal_lex.sym != rparent_sym) {
  483.             error(5, NULL);
  484.             return;
  485.         }
  486.         cal_next_symbol();
  487.         
  488.     } else if (cal_lex.sym == cvunit_sym) {
  489.         char from_unit[MAX_LINE_LENGTH];
  490.         char to_unit[MAX_LINE_LENGTH];
  491.         
  492.         cal_next_symbol();
  493.         if (cal_lex.sym != lparent_sym) {
  494.             error(63, NULL);
  495.             return;
  496.         }
  497.         cal_next_symbol();
  498.         
  499.         expr(&f);
  500.         if (cal_err)
  501.             return;
  502.         
  503.         if (cal_lex.sym != comma_sym) {
  504.             error(63, NULL);
  505.             return;
  506.         }
  507.  
  508.         cal_next_symbol();
  509.         if (cal_lex.sym != ident_sym) {
  510.             error(63, NULL);
  511.             return;
  512.         }
  513.         
  514.         strcpy(from_unit, cal_lex.id);
  515.         
  516.         cal_next_symbol();
  517.  
  518.     /* The unit name may consist of two names, such as "sq yard" */
  519.  
  520.     if (cal_lex.sym == ident_sym) {
  521.         strcat(from_unit, /*MSG0*/" ");
  522.             strcat(from_unit, cal_lex.id);
  523.             cal_next_symbol();
  524.     }
  525.  
  526.         if (cal_lex.sym != comma_sym) {
  527.             error(63, NULL);
  528.             return;
  529.         }
  530.  
  531.         cal_next_symbol();
  532.         if (cal_lex.sym != ident_sym) {
  533.             error(63, NULL);
  534.             return;
  535.         }
  536.         
  537.         strcpy(to_unit, cal_lex.id);
  538.  
  539.         cal_next_symbol();
  540.  
  541.     /* The unit name may consist of two names, such as "sq yard" */
  542.  
  543.     if (cal_lex.sym == ident_sym) {
  544.         strcat(to_unit, /*MSG0*/" ");
  545.             strcat(to_unit, cal_lex.id);
  546.             cal_next_symbol();
  547.     }
  548.  
  549.         if (cal_lex.sym != rparent_sym) {
  550.             error(63, NULL);
  551.             return;
  552.         }
  553.         
  554.         switch (f.type) {
  555.             
  556.         case real_type:
  557.         case int_type:
  558.             f.type = real_type;
  559.             success = ads_cvunit(f.r, from_unit, to_unit, &f.r);
  560.             break;
  561.         case vector_type:
  562.             success = ads_cvunit(f.v[X], from_unit, to_unit, &f.v[X]);
  563.             if (success != RTNORM)
  564.                 break;
  565.             success = ads_cvunit(f.v[Y], from_unit, to_unit, &f.v[Y]);
  566.             if (success != RTNORM)
  567.                 break;
  568.             success = ads_cvunit(f.v[Z], from_unit, to_unit, &f.v[Z]);
  569.             if (success != RTNORM)
  570.                 break;
  571.             break;
  572.         default:
  573.             return;
  574.         } /*switch*/
  575.         
  576.         if (success != RTNORM) {
  577.             error(64, NULL);
  578.             return;
  579.         }
  580.         cal_next_symbol();
  581.  
  582.     } else if (cal_lex.sym == at_sym) {
  583.         struct resbuf buff;
  584.  
  585.         f.type = vector_type;
  586.         ads_getvar(/*MSG0*/"LASTPOINT", &buff);
  587.         CPY_PNT(f.v, buff.resval.rpoint);
  588.         cal_next_symbol();
  589.  
  590.     } else if (cal_lex.sym == lparent_sym) {
  591.         cal_next_symbol();
  592.         expr(&f);
  593.         if (cal_err)
  594.             return;
  595.         if (cal_lex.sym == rparent_sym) {
  596.             cal_next_symbol();
  597.         } else {
  598.             error(5, NULL);
  599.             return;
  600.         }
  601.  
  602.     } else if (cal_lex.sym == lbracket_sym) {
  603.         vector(&f);
  604.     } else if (cal_lex.sym == no_sym) {
  605.         error(9, NULL);
  606.         return;
  607.     } else {
  608.         error(10, NULL);
  609.         return;
  610.     }
  611.  
  612.     check_overflow(&f, 0);
  613.  
  614.     if (cal_err)
  615.         return;
  616.  
  617.     if (is_minus) {
  618.         if (f.type == vector_type) {
  619.             f.v[X] = -f.v[X];
  620.             f.v[Y] = -f.v[Y];
  621.             f.v[Z] = -f.v[Z];
  622.         } else {
  623.             f.r = -f.r;
  624.         }
  625.     }
  626.  
  627.     *value = f;
  628. } /*factor*/
  629.  
  630.  
  631. /****************************************************************************/
  632. /*.doc power(internal)*/
  633. /*+
  634.   Parsing the nonterminal symbol POWER = FACTOR^FACTOR^...
  635. -*/
  636. /****************************************************************************/
  637.  
  638.  
  639. static void
  640. /*FCN*/power(value)
  641.  
  642.   vector_real_int *value;
  643. {
  644.     vector_real_int p, f;
  645.  
  646.     if (cal_err)
  647.         return;
  648.  
  649.     factor(&p);
  650.  
  651.     if (cal_err)
  652.         return;
  653.  
  654.     while (cal_lex.sym == caret_sym) {
  655.         cal_next_symbol();
  656.         factor(&f);
  657.         if (cal_err)
  658.             return;
  659.         if ((p.type == vector_type) || (f.type == vector_type)) {
  660.             error(16, NULL);
  661.             return;
  662.         }
  663.  
  664.         p.type = real_type;
  665.  
  666.         if (p.r == 0.0) {
  667.             ;                         /*p.r = 0.0*/
  668.         } else if (f.r == 0.0) {
  669.             p.r = 1.0;
  670.         } else {
  671.             if ((p.r < 0.0) && (f.r != (int)f.r)) {
  672.                 error(17, NULL);
  673.                 return;
  674.             }
  675.             p.r = pow(p.r, f.r);
  676.             if (!check_overflow(&p, 25))
  677.                 return;
  678.         }
  679.     } /*while*/
  680.  
  681.     check_overflow(&p, 0);
  682.  
  683.     *value = p;
  684. } /*power*/
  685.  
  686.  
  687. /****************************************************************************/
  688. /*.doc term(internal)*/
  689. /*+
  690.   Parsing the nonterminal symbol TERM = POWER*POWER*...
  691. -*/
  692. /****************************************************************************/
  693.  
  694.  
  695. static void
  696. /*FCN*/term(value)
  697.  
  698.   vector_real_int *value;
  699. {
  700.     vector_real_int t, p, tmp;
  701.     symbol_type     oper;
  702.  
  703.     if (cal_err)
  704.         return;
  705.  
  706.     power(&t);
  707.     if (cal_err)
  708.         return;
  709.  
  710.     while ((cal_lex.sym == asterisk_sym) ||
  711.            (cal_lex.sym == slash_sym)    ||
  712.            (cal_lex.sym == ampersand_sym)) {
  713.  
  714.         oper = cal_lex.sym;
  715.         cal_next_symbol();
  716.         power(&p);
  717.  
  718.         if (cal_err)
  719.             return;
  720.  
  721.         switch (oper) {
  722.  
  723.         case asterisk_sym:
  724.             if ((t.type != vector_type) && (p.type != vector_type)) {
  725.                 if (p.type == real_type) {
  726.                     t.type = real_type;
  727.                 }
  728.                 t.r *= p.r;
  729.  
  730.             } else if ((t.type == vector_type) && (p.type == vector_type)) {
  731.                 t.type = real_type;
  732.                 t.r    = DOTPROD(t.v, p.v);
  733.  
  734.             } else if ((t.type == vector_type) && (p.type != vector_type)) {
  735.                 t.type = vector_type;
  736.                 t.v[X] *= p.r;
  737.                 t.v[Y] *= p.r;
  738.                 t.v[Z] *= p.r;
  739.             } else {
  740.                 t.type = vector_type;
  741.                 t.v[X] = p.v[X] * t.r;
  742.                 t.v[Y] = p.v[Y] * t.r;
  743.                 t.v[Z] = p.v[Z] * t.r;
  744.             }
  745.             break;
  746.  
  747.         case slash_sym:
  748.             if (fabs(p.r) < EPS) {
  749.                 error(18, NULL);
  750.                 return;
  751.             }
  752.             if ((t.type != vector_type) && (p.type != vector_type)) {
  753.                 t.type = real_type;
  754.                 t.r /= p.r;
  755.  
  756.             } else if ((t.type == vector_type) && (p.type != vector_type)) {
  757.                 t.v[X] /= p.r;
  758.                 t.v[Y] /= p.r;
  759.                 t.v[Z] /= p.r;
  760.             } else {
  761.                 error(19, NULL);
  762.                 return;
  763.             }
  764.             break;
  765.  
  766.         case ampersand_sym:           /*Cross product*/
  767.             if ((t.type == vector_type) && (p.type == vector_type)) {
  768.                 tmp.type = vector_type;
  769.                 tmp.v[X] = t.v[Y] * p.v[Z] - t.v[Z] * p.v[Y];
  770.                 tmp.v[Y] = t.v[Z] * p.v[X] - t.v[X] * p.v[Z];
  771.                 tmp.v[Z] = t.v[X] * p.v[Y] - t.v[Y] * p.v[X];
  772.                 t = tmp;
  773.             } else {
  774.                 error(20, NULL);
  775.                 return;
  776.             }
  777.             break;
  778.         } /*switch*/
  779.  
  780.         if(!check_overflow(&t, 0))
  781.             return;
  782.     } /*while*/
  783.  
  784.     check_overflow(&t, 0);
  785.  
  786.     *value = t;
  787. } /*term*/
  788.  
  789.  
  790. /****************************************************************************/
  791. /*.doc expr(internal)*/
  792. /*+
  793.     Parsing the nonterminal symbol EXPR = TERM+TERM+...
  794. -*/
  795. /****************************************************************************/
  796.  
  797.  
  798. static void
  799. /*FCN*/expr(value)
  800.  
  801.   vector_real_int *value;
  802. {
  803.     vector_real_int e, t;
  804.     symbol_type     oper;
  805.  
  806.     if (cal_err)
  807.         return;
  808.  
  809.     term(&e);
  810.     if (cal_err)
  811.         return;
  812.  
  813.     while ((cal_lex.sym == plus_sym) || (cal_lex.sym == minus_sym)) {
  814.  
  815.         oper = cal_lex.sym;
  816.         cal_next_symbol();
  817.  
  818.         term(&t);
  819.  
  820.         if (cal_err)
  821.             return;
  822.  
  823.         switch (oper) {
  824.  
  825.         case plus_sym:
  826.             if ((e.type != vector_type) && (t.type != vector_type)) {
  827.                 if (t.type == real_type) {
  828.                     e.type = real_type;
  829.                 }
  830.                 e.r += t.r;
  831.  
  832.             } else if ((e.type == vector_type) && (t.type == vector_type)) {
  833.                 ADD_PNT(e.v, e.v, t.v);
  834.             } else {
  835.                 error(21, NULL);
  836.                 return;
  837.             }
  838.             break;
  839.  
  840.         case minus_sym:
  841.             if ((e.type != vector_type) && (t.type != vector_type)) {
  842.                 if (t.type == real_type) {
  843.                     e.type = real_type;
  844.                 }
  845.                 e.r -= t.r;
  846.  
  847.             } else if ((e.type == vector_type) && (t.type == vector_type)) {
  848.                 SUB_PNT(e.v, e.v, t.v);
  849.             } else {
  850.                 error(21, NULL);
  851.                 return;
  852.             }
  853.         } /*switch*/
  854.  
  855.         if (!check_overflow(&e, 0))
  856.             return;
  857.     } /*while*/
  858.  
  859.     check_overflow(&e, 0);
  860.  
  861.     *value = e;
  862. } /*expr*/
  863.  
  864.  
  865. /****************************************************************************/
  866. /*.doc cal_evaluate_expression(external)*/
  867. /*+
  868.   The top-level expression-evalution function.
  869.  
  870.   The function returns TRUE if succeeds, or FALSE if it fails.
  871. -*/
  872. /****************************************************************************/
  873.  
  874.  
  875. int
  876. /*FCN*/cal_evaluate_expression(line, value)
  877.  
  878.   char            *line;              /* Input expression as a string */
  879.   vector_real_int *value;             /* Returned value of expression */
  880. {
  881.     vector_real_int val;
  882.     char            id[MAX_SYMBOL_LENGTH+1];
  883.     struct resbuf   rb;
  884.     int             success;
  885.  
  886.     cal_lex_start(line);
  887.  
  888.     /* Check whether the expression begins with 'VAR=' assignment */
  889.  
  890.     id[0] = EOS;
  891.     if (cal_lex.sym == ident_sym) {
  892.         strcpy(id, cal_lex.id);       /* It might be assignment */
  893.         cal_next_symbol();
  894.         if (cal_err) 
  895.             return(FALSE);
  896.  
  897.         if (cal_lex.sym != equal_sym) {
  898.             id[0] = EOS;              /* No, it isn't assignment */
  899.             cal_lex_start(line);
  900.         } else {
  901.             cal_next_symbol();
  902.         }
  903.     }
  904.     if (cal_err)
  905.         return(FALSE);
  906.  
  907.     expr(&val);                       /* Start the expression evaluation */
  908.  
  909.     if (cal_err)
  910.         return(FALSE);
  911.  
  912.     if (cal_lex.sym != no_sym) {
  913.         error(10, NULL);
  914.         return(FALSE);
  915.     }
  916.  
  917.     if ((val.type == int_type) &&
  918.         ((val.r > 32767) || (val.r < -32768))) {
  919.         error(41, NULL);
  920.         return(FALSE);
  921.     }
  922.  
  923.     /* Assign value of expression to AutoLISP variable, if available */
  924.  
  925.     if (id[0] != EOS) {
  926.         switch (val.type) {
  927.         case int_type:
  928.             rb.restype = RTSHORT;
  929.             rb.resval.rint = (int)val.r;
  930.             break;
  931.         case real_type:
  932.             rb.restype = RTREAL;
  933.             rb.resval.rreal = val.r;
  934.             break;
  935.         case vector_type:
  936.             rb.restype = RT3DPOINT;
  937.             CPY_PNT(rb.resval.rpoint, val.v);
  938.             break;
  939.         default:
  940.             error(-443, NULL);
  941.             return(FALSE);
  942.         } /*switch*/
  943.  
  944.         rb.rbnext = NULL;
  945.  
  946.         success = ads_putsym(id, &rb);
  947.         if (success != RTNORM) {
  948.             error(29, id);
  949.             return(FALSE);
  950.         }
  951.     } /*if*/
  952.  
  953.     *value = val;
  954.     return(TRUE);
  955. } /*evaluate_expression*/
  956.  
  957.  
  958.